Skip to main content
Circuit depth is critical to performance and correctness in PVAC-HFHE. This guide explains how depth affects ciphertexts and how to manage it.

What is circuit depth?

Circuit depth is the longest path of multiplications from inputs to output:
Additions and subtractions do not increase depth. Only multiplications increase depth by 1.

Depth vs performance

From benchmark data (benchmarks/README.md:88-98):
Ciphertext size and computation time grow exponentially with depth. At d4, PVAC-HFHE ciphertexts exceed BFV in size.

Depth examples

Depth 1: Single multiplication

From examples/basic_usage.cpp:150-158:

Depth 3: Polynomial evaluation

Evaluating f(x) = x³ + 2x² + 3x + 4 requires depth 3:
Actual depth is 2 due to parallel evaluation.

Depth 4: x^16

From examples/basic_usage.cpp:159-162:

Ciphertext growth

Ciphertexts grow because multiplication creates product layers:

Edge count growth

For multiplication C = ct_mul(A, B) with S=8 edges per layer:
Example:
  • Fresh encryption: ~300 edges, 1 layer
  • After 1 mul: ~900 edges, 2 layers
  • After 2 muls: ~2700 edges, 4 layers
  • After 3 muls: ~8100 edges, 8 layers
The edge budget parameter (default 1,200,000) triggers automatic compaction when exceeded.

Layer count growth

Layers grow quadratically with each multiplication.

Noise budget

PVAC-HFHE uses an entropy-based noise budget. From include/pvac/ops/encrypt.hpp:200-213:

Default parameters

  • noise_entropy_bits = 120.0
  • tuple2_fraction = 0.55
  • depth_slope_bits = 16.0
Budget at depth d:
Higher depth allocates more noise terms, increasing encryption time but enabling deeper computations.

Depth hints

Use enc_value_depth to preallocate noise budget:
From include/pvac/ops/encrypt.hpp:732-738:

When to use depth hints

Over-estimating depth wastes computation time and increases ciphertext size. Under-estimating may cause decryption failures.

Compaction strategies

PVAC-HFHE automatically compacts ciphertexts when edge budget is exceeded:

Edge compaction

From include/pvac/ops/encrypt.hpp:658-660:
Merges edges with the same (layer_id, idx, ch) triple.

Layer compaction

From include/pvac/ops/encrypt.hpp:662-707: Removes unused layers and renumbers layer IDs.

Budget guard

From include/pvac/ops/encrypt.hpp:709-714:
Automatically triggered after every arithmetic operation.

Benchmarking depth

From examples/basic_usage.cpp:246-265:

Comparison with RLWE schemes

From benchmark data:
PVAC-HFHE has exponential degradation at deep depths, while RLWE schemes maintain near-constant time via modulus switching. PVAC excels at shallow circuits (d ≤ 2).

Optimization tips

Minimize depth

Use additions freely

Batch multiplications

Next steps

Performance tuning

Advanced optimization techniques

Arithmetic operations

Master ct_mul and ct_square